package com.hcss.sys.role.service.impl;

import com.hcss.common.base.BaseClass;
import com.hcss.common.constant.CommonConstants;
import com.hcss.common.shiro.ShiroProperties;
import com.hcss.common.util.SerializeUtils;
import com.hcss.login.constant.LoginConstants;
import com.hcss.qywechat.user.model.vo.WQyUserVO;
import com.hcss.sys.role.constant.RoleConstants;
import com.hcss.sys.role.dao.HcSysRoleComplexMapper;
import com.hcss.sys.role.dao.HcSysRoleMapper;
import com.hcss.sys.role.dao.HcSysRolemenuMapper;
import com.hcss.sys.role.dao.HcSysRoleuserMapper;
import com.hcss.sys.role.model.*;
import com.hcss.sys.role.model.vo.HcSysRolemenuVO;
import com.hcss.sys.role.service.RoleService;
import com.hcss.util.EmptyUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @描述: RoleService服务的实现类
 * @作者: fangtao
 * @创建日期: 2019-01-08 10:46:19
 */
@Service("roleService")
public class RoleServiceImpl implements RoleService {
	
	@Autowired
	private HcSysRoleMapper hcSysRoleMapper;

	@Autowired
	private HcSysRoleComplexMapper hcSysRoleComplexMapper;

	@Autowired
	private HcSysRolemenuMapper hcSysRolemenuMapper;

	@Autowired
	private HcSysRoleuserMapper hcSysRoleuserMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private ShiroProperties shiroProperties;

	@Override
	public boolean checkCodeUnique(String code, String id) {
		HcSysRoleExample example = new HcSysRoleExample();
		example.createCriteria().andCodeEqualTo(code);
		List<HcSysRole> list = hcSysRoleMapper.selectByExample(example);
		if (CollectionUtils.isEmpty(list)) {// 未查询到重复code，返回true
			return true;
		} else {
			if (StringUtils.isBlank(id)) {// 新增情况下，code重复返回false
				return false;
			} else {// 更新情况下，code不改变返回true
				return list.get(0).getId().equalsIgnoreCase(id);
			}
		}
	}

	@Override
	public void insertModel(HcSysRole model) {
		model.setId(BaseClass.getUUIDWithoutConnector());
		hcSysRoleMapper.insertSelective(model);
	}

	@Override
	public void updateModel(HcSysRole model) {
		hcSysRoleComplexMapper.updateByPrimaryKey(model);
	}

	@Override
	public void deleteById(HcSysRole model) {
		model.setStatus(RoleConstants.STATUS_DELETE);
		hcSysRoleComplexMapper.updateByPrimaryKey(model);
		// 清除全部角色用户的登录信息
        clearAllLoginUserSession(model.getId());
	}

	@Override
	public HcSysRole selectByPK(String id) {
		if (EmptyUtil.isHaveEmpty(id)) {
            return null;
        }
        return hcSysRoleComplexMapper.selectByPrimaryKey(id);
	}

	@Override
	public List<HcSysRole> selectAll() {
		HcSysRoleExample example = new HcSysRoleExample();
		example.createCriteria().andStatusEqualTo(RoleConstants.STATUS_NORMAL);
		return hcSysRoleMapper.selectByExample(example);
	}

	@Override
	public List<HcSysRole> selectByMenu(HcSysRolemenuVO roleMenuVO) {
		return hcSysRoleComplexMapper.selectRoleByMenuid(roleMenuVO.getMenuid());
	}

	@Override
	public void saveRoleMenu(HcSysRolemenuVO model) {
		hcSysRoleComplexMapper.insert(model);
	}

	@Override
	public void deleteRoleMenu(HcSysRolemenuVO model) {
		HcSysRolemenuExample example = new HcSysRolemenuExample();
		example.createCriteria().andMenuidEqualTo(model.getMenuid())
				.andRoleidEqualTo(model.getRoleid());
		hcSysRolemenuMapper.deleteByExample(example);
	}

	@Override
	public void saveRoleUser(HcSysRoleuser model) {
		hcSysRoleuserMapper.insert(model);
	    // 清除roleid的userid的登录用户信息
        clearLoginUserSession(model.getUserid());
	}

	@Override
	public void deleteRoleUser(HcSysRoleuser model) {
		HcSysRoleuserExample example = new HcSysRoleuserExample();
		example.createCriteria().andRoleidEqualTo(model.getRoleid()).andUseridEqualTo(model.getUserid());
		hcSysRoleuserMapper.deleteByExample(example);
        // 清除roleid的userid的登录用户信息
        clearLoginUserSession(model.getUserid());
	}

	@Override
	public void batchSaveRoleMenu(String roleid, List<String> menuidList) {
		deleteRoleMenuByRoleid(roleid);

		List<HcSysRolemenuVO> data = new ArrayList<>(menuidList.size());
		for (String menuid : menuidList) {
			data.add(new HcSysRolemenuVO().setMenuid(menuid).setRoleid(roleid));
		}
		hcSysRoleComplexMapper.insertBatch(data);

	}

	@Override
	public void deleteRoleMenuByRoleid(String roleid) {
		HcSysRolemenuExample example = new HcSysRolemenuExample();
		example.createCriteria().andRoleidEqualTo(roleid);
		hcSysRolemenuMapper.deleteByExample(example);
	}

	@Override
	public List<Map<String, String>> selectUserByRole(String roleid) {
		return hcSysRoleComplexMapper.selectUserByRoleid(roleid);
	}

    @Override
    public boolean isUserHaveMenuRole(String userid, String menuUrl) {
        List<HcSysRoleuser> list = hcSysRoleComplexMapper.selectUserRoleByMenu(userid, menuUrl);
        return CollectionUtils.isNotEmpty(list);
    }

    /**
     * 清除角色全部登录用户
     * @param roleid
     */
    private void clearAllLoginUserSession(String roleid) {
        List<HcSysRoleuser> users = getUsersByRole(roleid);
        if (CollectionUtils.isNotEmpty(users)) {
            Set<String> keys = redisTemplate.keys(shiroProperties.getRedis().getNamePrefix() + CommonConstants.COLON + CommonConstants.STAR);
            for (String key : keys) {
                String value = redisTemplate.opsForValue().get(key);
                Session session = SerializeUtils.deserializeFromString(value);
                Object obj = session.getAttribute(LoginConstants.REDIS_LOGINUSER_KEY);
                if (obj != null) {
                    WQyUserVO user = (WQyUserVO) ((SimplePrincipalCollection) obj).getPrimaryPrincipal();
                    for (HcSysRoleuser roleuser : users) {
                        if (roleuser.getUserid().equals(user.getUserid())) {
                            redisTemplate.delete(key);
                        }
                    }
                }
            }
        }
    }

    /**
     * 清除userid的登录session
     * @param userid
     */
    private void clearLoginUserSession(String userid) {
        Set<String> keys = redisTemplate.keys(shiroProperties.getRedis().getNamePrefix() + CommonConstants.COLON + CommonConstants.STAR);
        for (String key : keys) {
            String value = redisTemplate.opsForValue().get(key);
            Session session = SerializeUtils.deserializeFromString(value);
            Object obj = session.getAttribute(LoginConstants.REDIS_LOGINUSER_KEY);
            if (obj != null) {
                WQyUserVO user = (WQyUserVO) ((SimplePrincipalCollection) obj).getPrimaryPrincipal();
                if (userid.equals(user.getUserid())) {
                    redisTemplate.delete(key);
                }
            }
        }
    }

    /**
     * 获取角色拥有的用户信息
     * @param roleid
     * @return
     */
    private List<HcSysRoleuser> getUsersByRole(String roleid) {
        HcSysRoleuserExample example = new HcSysRoleuserExample();
        example.createCriteria().andRoleidEqualTo(roleid);
        return hcSysRoleuserMapper.selectByExample(example);
    }
}
